//! 使用`cargo expand --package redis --lib commands`命令可以展开[implement_commands]宏
//!
//! 展开后的代码[command.rs](command.rs)
//!
//! `impl<T> Commands for T
//!     where
//!         T: ConnectionLike,
//! {}`
//!
//! 即实现了[ConnectionLike] trait 则实现了[Commands] trait
//!
//! 又因为
//!
//! `impl<C, T> ConnectionLike for T
//! where
//!     C: ConnectionLike,
//!     T: DerefMut<Target = C>,
//! {
//!     ...
//! }`
//!
//! `impl<M> DerefMut for PooledConnection<M>
//! where
//!     M: ManageConnection,
//! {
//!     ...
//! }`
//!
//! 所以[PooledConnection<Client>]实现了[ConnectionLike] trait
//!
//! 即[PooledConnection<Client>]实现了[Commands] trait
//!

use bb8::Pool;
use bb8_redis::RedisConnectionManager;
use r2d2::PooledConnection;
use redis::aio::MultiplexedConnection;
use redis::{Client, Connection};
use std::time::Duration;

/// 通过连接池获取redis连接
pub fn get_conn() -> anyhow::Result<PooledConnection<Client>> {
    let client = get_client()?;
    let pool = r2d2::Pool::builder().build(client)?;
    let conn = pool.get()?;

    Ok(conn)
}

/// 获取原生的redis连接
pub fn get_conn1() -> redis::RedisResult<Connection> {
    let client = get_client()?;
    let conn = client.get_connection()?;
    Ok(conn)
}

/// 获取redis Client
///
/// 复杂的获取方式
/// ```
///  use redis::{Client, ConnectionAddr, ConnectionInfo, RedisConnectionInfo};
///  let addr = ConnectionAddr::Tcp("39.105.80.131".to_string(), 3978);
///  let redis = RedisConnectionInfo{
///     db: 50,
///     password: Some("haoyue@123456..".to_string()),
///     ..Default::default()
///   };
///  let params = ConnectionInfo{
///     addr,
///     redis
///  };
///  let client = Client::open(params)?;
/// ```
///
/// redis url 格式: `{redis|rediss}://[<username>][:<password>@]<hostname>[:port][/<db>]`
fn get_client() -> redis::RedisResult<Client> {
    let client = Client::open("redis://:haoyue@123456..@39.105.80.131:3978/50")?;
    Ok(client)
}


/// 获取异步连接
pub async fn get_aysnc_conn() -> redis::RedisResult<MultiplexedConnection> {
    let client = get_client()?;
    let con = client.get_multiplexed_async_connection().await?;

    Ok(con)
}


pub async fn get_pool() -> Pool<RedisConnectionManager> {
    let manager = RedisConnectionManager::new("redis://:123456@172.28.217.80:6379/0").unwrap();
    let pool = Pool::builder()
        .max_size(10)
        .min_idle(2)
        .connection_timeout(Duration::from_secs(10))
        .idle_timeout(Duration::from_secs(10))
        .build(manager)
        .await;

    match pool {
        Ok(c) => c,
        Err(e) => panic!("redis创建连接失败：{}", e),
    }
}
